﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Cofe.Core.Script
{
    public class ResultCommand : ScriptCommandBase
    {
        public static ResultCommand OK = new ResultCommand();
        public static ResultCommand Error(Exception ex) { return new ResultCommand(ex); }

        Action<ParameterDic> _executeFunc = (pm) => { };
        private ResultCommand(Exception ex = null)
            : base( ex == null ? "OK" : "FAIL")
        {
            if (ex == null)
                _executeFunc = (pm) => { pm.IsHandled = true; };
            else _executeFunc = (pm) => { pm.Error = ex; };
        }

        public override IScriptCommand Execute(ScriptParameterDic pm)
        {
            _executeFunc(pm);
            return null;
        }
        
    }

    public class ChangeDirectoryScriptCommand : ScriptCommandBase
    {
        #region Constructor

        public ChangeDirectoryScriptCommand()
            : base("ChangeDirectory", "Path")
        {

        }

        #endregion

        #region Methods

        public override bool CanExecute(ScriptParameterDic pm)
        {
            return base.CanExecute(pm) && pm.ContainsKey("Path") && pm["Path"] is string;
        }

        public override IScriptCommand Execute(ScriptParameterDic pm)
        {
            if (CanExecute(pm))
            {
                string path = pm["Path"] as string;
                pm.CurrentDir = EntryFE.TryParsePathAsync<ICofeDirectoryInfo>(path, ParsableType.ParsePathLookup).Result;
            }
            return null;
        }

        #endregion

        #region Data

        #endregion

        #region Public Properties

        #endregion

    }

    //public class ListScriptCommand : ScriptCommandBase
    //{
    //    #region Constructor

    //    public ListScriptCommand()
    //        : base("List", "FilterStr")
    //    {

    //    }

    //    #endregion

    //    #region Methods

    //    public override bool CanExecute(ScriptParameterDic pm)
    //    {
    //        return base.CanExecute(pm) && pm.ContainsKey("Path") && pm["Path"] is string;
    //    }

    //    public override void Execute(ScriptParameterDic pm)
    //    {
    //        if (CanExecute(pm))
    //        {
    //            string path = pm["Path"] as string;
    //            pm.CurrentDir = EntryFE.TryParsePathAsync<ICofeDirectoryInfo>(path, ParsableType.ParsePathLookup).Result;
    //        }
    //    }

    //    #endregion

    //    #region Data

    //    #endregion

    //    #region Public Properties

    //    #endregion

    //}


    public class EntryScriptCommand : ScriptCommandBase
    {

        #region Constructor

        private EntryScriptCommand(object property)
            : base(CofeServices.PropertyDictionary.GetPropertyString(property))
        {
            _property = property;
            if (!(DecoratorExtension.IsAction(_property)))
                throw new ArgumentException(property.ToString() + " is not an action.");
        }

        public static EntryScriptCommand FromProperty(object property)
        {
            return new EntryScriptCommand(property);
        }

        #endregion

        #region Methods

        public override IScriptCommand Execute(ScriptParameterDic pm)
        {
            foreach (var entry in pm.SelectedEntries)
                if (entry.Properties.Behaviors.IsPropertySupported(_property))
                    entry.Properties.Behaviors.Invoke(_property, pm.Clone());
            return null;
        }

        public override bool CanExecute(ScriptParameterDic pm)
        {
            foreach (var entry in pm.SelectedEntries)
                if (entry.Properties.Behaviors.IsPropertySupported(_property))
                    return true;
            return false;
        }

        #endregion

        #region Data

        private object _property;

        #endregion

        #region Public Properties

        #endregion

    }


}
